﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FitAutomation.FitProcess;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using MyUtils;


namespace FitProcess_UnitTests
{

	[TestClass]
	public class Should_manipulate_class_in_another_parocess
	{
		[ClassInitialize]
		public static void Init(TestContext c)
		{
			DebugUtils.DebuggerReattaching();
			_process1 = FitProcessFactory.CreateProcess(Debugger.IsAttached, true);
		}

		[ClassCleanup]
		public static void Clean()
		{
			_process1.Close();
		}

		static FitProcessAccessor _process1;

		static int MyProcessId { get { return Process.GetCurrentProcess().Id; } }

		[TestMethod]
		public void Start_another_process()
		{
			_process1.NewObject<MyClass>("obj1");

			var response = _process1["obj1"].Reflect("ProcessID");

			Assert.IsNotNull(response);
			Assert.IsInstanceOfType(response, typeof(int));

			var id = (int)response;

			Assert.IsTrue(id > 0);
			Assert.AreNotEqual(id, MyProcessId);
		}

		[TestMethod]
		public void Start_another_process_generic()
		{
			_process1.NewObject<MyClass>("obj1");

			var id = _process1["obj1"].Reflect<int>("ProcessID");

			Assert.IsTrue(id > 0);
			Assert.AreNotEqual(id, MyProcessId);
		}

		[TestMethod]
		public void Should_assignvariables()
		{
			_process1.NewObject<MyClass>("obj2");

			_process1["obj2"].Reflect("Field", 5);

			Assert.AreEqual(5, _process1["obj2"].Reflect("Field"));
		}

		[TestMethod]
		[ExpectedException(typeof(RemoteException))]
		public void Should_throw()
		{
			_process1.NewObject<MyClass>("obj3");
			_process1["obj3"].Reflect("throw");
		}

		[TestMethod]
		public void Should_allow_pass_some_struct()
		{
			_process1.NewObject<MyClass>("obj4");
			_process1["obj4"].Reflect("SomeStruct", new MyStruct{A=3, B=4});

			var s = (MyStruct)_process1["obj4"].Reflect("SomeStruct");

			Assert.AreEqual(3, s.A);
			Assert.AreEqual(4, s.B);
		}

		static int RunStatic()
		{
			return Process.GetCurrentProcess().Id;
		}

		[TestMethod]
		public void Should_alow_make_static_call()
		{
			Assert.Inconclusive();
//			var id = _process1.ReflectStatic(typeof(Should_manipulate_class_in_another_parocess), "RunStatic");
//			Assert.IsTrue(id > 0);
//			Assert.AreNotEqual(id, RunStatic());
		}

		[TestMethod]
		public void Should_alow_create_anonim_objects()
		{
			var obj = _process1.NewObject<MyClass>();

			obj.Reflect("Field", 5);

			Assert.AreEqual(5, obj.Reflect("Field"));

		}

	}
}
